package com.gpframework.module.module.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gpframework.common.constant.BrandConstants;
import com.gpframework.common.constant.Constants;
import com.gpframework.common.constant.HttpStatus;
import com.gpframework.common.core.domain.TreeSelect;
import com.gpframework.common.core.domain.entity.SysDept;
import com.gpframework.common.core.domain.entity.SysMenu;
import com.gpframework.common.core.domain.entity.SysRole;
import com.gpframework.common.core.domain.entity.SysUser;
import com.gpframework.common.enums.UserStatus;
import com.gpframework.common.exception.CustomException;
import com.gpframework.common.utils.IdGenUtils;
import com.gpframework.module.common.domain.CommonWxUser;
import com.gpframework.module.common.mapper.CommonWxUserMapper;
import com.gpframework.module.module.domain.BrandAuditRecord;
import com.gpframework.module.module.domain.BrandInfo;
import com.gpframework.module.module.domain.req.BrandAuditRecordReq;
import com.gpframework.module.module.domain.vo.BrandAuditRecordVo;
import com.gpframework.module.module.domain.vo.BrandInfoVo;
import com.gpframework.module.module.mapper.BrandAuditRecordMapper;
import com.gpframework.module.module.mapper.BrandInfoMapper;
import com.gpframework.module.module.service.IBrandAuditRecordService;
import com.gpframework.module.module.service.IBrandInfoService;
import com.gpframework.module.pay.utils.joinpay.sdk.utitls.StringUtil;
import com.gpframework.module.system.domain.SysPost;
import com.gpframework.module.system.domain.SysUserRole;
import com.gpframework.module.system.mapper.*;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName BrandAuditRecord
 * @Author gpframework
 * @Date 2022-03-23
 * @Version 1.0.0
 * @Description 品牌审核Service业务层处理
 */
@Service
public class BrandAuditRecordServiceImpl extends ServiceImpl<BrandAuditRecordMapper, BrandAuditRecord> implements IBrandAuditRecordService {
    protected Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 品牌信息业务层
     */
    @Autowired
    private IBrandInfoService brandInfoService;

    /**
     * 用户表持久层接口
     */
    @Autowired
    private SysUserMapper sysUserMapper;
    /**
     * 角色表持久层接口
     */
    @Autowired
    private SysRoleMapper sysRoleMapper;

    /**
     * 岗位信息持久层接口
     */
    @Autowired
    private SysPostMapper sysPostMapper;

    /**
     * 菜单持久层接口
     */
    @Autowired
    private SysMenuMapper sysMenuMapper;

    /**
     * 部门持久层接口
     */
    @Autowired
    private SysDeptMapper sysDeptMapper;


    /**
     * 消息模板业务层接口
     */
    @Autowired
    private CommonWxUserMapper commonWxUserMapper;

    /**
     * 用户角色持久层接口
     */
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    /**
     * 生成雪花id
     */
    private Snowflake snowflake = IdUtil.getSnowflake(1, 1);

    /**
     * @Description 查询列表返回VO 用于返回给前端的列表接口
     * @Author gpframework
     * @Date 2022-03-23
     * @Param [lqw]
     * @Return List<BrandAuditRecordVo>
     */
    @Override
    public List<BrandAuditRecordVo> listVo(QueryWrapper<BrandAuditRecord> lqw) {
        return this.baseMapper.listVo(lqw);
    }

    /**
     * @Description 通过查询详情VO 用于返回给前端的列详情接口
     * @Author gpframework
     * @Date 2022-03-23
     * @Param [id]
     * @Return BrandAuditRecordVo
     */
    @Override
    public BrandAuditRecordVo getVoById(Long id) {
        return this.baseMapper.getVo(id);
    }

    /**
     * 修改审核信息
     *
     * @param brandAuditRecord
     * @return
     */
    @Override
    @Transactional
    public boolean edit(BrandAuditRecord brandAuditRecord) {
        Boolean success = false;
        BrandAuditRecordReq brandAuditRecordReq = new BrandAuditRecordReq();
        brandAuditRecordReq.setBrandId(brandAuditRecord.getBrandId());
        brandAuditRecordReq.setStatus(1);
        BrandAuditRecordVo brandAuditRecordVo = baseMapper.findByBrandId(brandAuditRecordReq);
        if (StringUtils.isEmpty(brandAuditRecordVo)) {
            logger.info("----------审核信息不存在：auditRecordId=" + brandAuditRecord.getBrandId() + "----------");
            return success;
        }
        if (brandAuditRecordVo.getStatus().equals(BrandConstants.AUDIT_SUCCESS)) {
            logger.info("----------该审核已通过不能修改：auditRecordId=" + brandAuditRecord.getAuditRecordId() + "----------");
            return success;
        }
        //品牌信息
//        BrandInfoVo brandInfoVo = brandInfoMapper.getVo(Long.parseLong(brandAuditRecordVo.getBrandId()));
        BrandInfoVo brandInfoVo = brandInfoService.getBrandInfo(Long.parseLong(brandAuditRecordVo.getBrandId()));
        if (StringUtils.isEmpty(brandInfoVo)) {
            logger.info("----------找不到品牌信息：brandId=" + brandAuditRecordVo.getBrandId() + "----------");
            return success;
        }
        if (brandInfoVo.getAuditStatus().equals(BrandConstants.AUDIT_SUCCESS)) {
            logger.info("----------品牌已通过审核：brandId=" + brandAuditRecordVo.getBrandId() + "----------");
            return success;
        }
        brandAuditRecord.setAuditRecordId(Long.parseLong(brandAuditRecordVo.getAuditRecordId()));
        //修改审核记录
        int i = baseMapper.updateById(brandAuditRecord);
        if (i <= 0) {
            logger.info("----------操作审核失败：auditRecordId=" + brandAuditRecord.getAuditRecordId() + "----------");
            return success;
        }
        BrandInfo brandInfo = Convert.convert(new TypeReference<BrandInfo>() {
        }, brandInfoVo);
        success = true;
        //审核通过
        if (brandAuditRecord.getStatus().equals(BrandConstants.AUDIT_SUCCESS)) {
            //创建系统登录用户
            SysUser sysUser = new SysUser(brandInfoVo.getBrandId(), brandInfoVo.getMobile(), brandInfoVo.getLeaderName(), brandInfoVo.getBrandLogo());
            sysUser.setIsAdmin(BrandConstants.IS_ADMIN);
            sysUser.setStoreId(BrandConstants.DEFAULT_BRAND_ID);
            sysUserMapper.insertUser(sysUser);
            //创建部门
            SysDept sysDept = initializeDept(brandInfoVo);
            //修改系统用户部门编号
            sysUser.setBrandDeptId(sysDept.getBrandDeptId());
            sysUserMapper.updateUser(sysUser);
            //修改品牌信息
            brandInfo.setBrandUserId(sysUser.getBrandUserId());
            brandInfo.setUserName(sysUser.getUserName());
            //初始化品牌角色
            initializeRole(brandInfo.getBrandId());
            //创建微信用户信息
            this.createUser(sysUser);
            //用户绑定品牌管理员角色
            this.userBindingRole(sysUser);
            // 添加默认问卷
//            this.createProblem(brandInfoVo.getBrandId());
            //初始化品牌岗位
            this.initializePost(brandInfo.getBrandId());
            //初始化品牌菜单
            this.initializeMenu(brandInfo.getBrandId());
            //发送短信通知品牌注册用户
//            commonPhoneMsgTemplateService.sendSms(0L, 0L, PhoneMsgTypeEnum.STORE_REGISTER.getKey(), PhoneMsgTypeEnum.STORE_REGISTER.getName(), Constants.MOBILE_AREA_CODE_CHINA, sysUser.getPhonenumber(), sysUser.getUserName() + "/123");
        }
        brandInfo.setAuditStatus(brandAuditRecord.getStatus());
//        i = brandInfoMapper.updateById(brandInfo);
        i = brandInfoService.updateBrandInfoById(brandInfo);
        if (i <= 0) {
            logger.info("----------修改品牌信息失败：brand=" + brandInfo + "----------");
            throw new CustomException("修改品牌信息失败", HttpStatus.NOT_FOUND);
        }
        return success;
    }

    // 添加默认问卷
//    private void createProblem(Long brandId) {
//        // 获取默认问卷
//        QueryWrapper<CommonProblem> cpLqw = new QueryWrapper<>();
//        cpLqw.eq("brand_id", 0);
//        cpLqw.eq("sort", 0); // 用sort=0作标识，代表默认的数据
//        cpLqw.eq("del_status", Constants.DEL_STATUS_FALSE);
//        List<CommonProblem> commonProblemList = commonProblemService.list(cpLqw);
//        if (CollectionUtils.isNotEmpty(commonProblemList)) {
//            commonProblemList.forEach(item -> {
//                Long problemId = item.getProblemId();
//                // 添加默认问卷
//                item.setProblemId(null);
//                item.setBrandId(brandId);
//                commonProblemService.save(item);
//                // 获取问卷详情
//                CommonProblemReq req = new CommonProblemReq();
//                req.setProblemId(problemId);
//                List<CommonProblemVo> commonProblemVos = commonProblemService.listVos(req);
//                if (CollectionUtils.isNotEmpty(commonProblemVos)) {
//                    // 获取问题列表
//                    CommonProblemVo commonProblemVo = commonProblemVos.get(0);
//                    List<CommonProblemQuestionUpdate> problemQuestionList = commonProblemVo.getProblemQuestions();
//                    // 重新定义一个list接收数据，不然会报ClassCastException
//                    List<CommonProblemQuestionUpdate> problemQuestions = new ArrayList<>();
//                    for (int i = 0; i < problemQuestionList.size(); i++) {
//                        CommonProblemQuestionUpdate problemQuestion = JSON.parseObject(JSON.toJSONString(problemQuestionList.get(i)), CommonProblemQuestionUpdate.class);
//                        problemQuestion.setProblemQuestionId(null);
//                        problemQuestion.setBrandId(brandId);
//                        problemQuestion.getOptions().forEach(options -> {
//                            options.setProblemQuestionId(null);
//                            options.setPid(null);
//                            options.setBrandId(brandId);
//                        });
//                        problemQuestions.add(problemQuestion);
//                    }
//                    commonProblemQuestionService.saveProblemQuestion(item, problemQuestions);
//                }
//            });
//        }
//    }

    /**
     * 初始化部门
     *
     * @param brandInfoVo
     */
    @Transactional
    public SysDept initializeDept(BrandInfoVo brandInfoVo) {
        if (StringUtils.isEmpty(brandInfoVo.getBrandId())) {
            logger.info("----------参数错误----------");
            throw new CustomException("参数错误", HttpStatus.NOT_FOUND);
        }
        SysDept sysDept = new SysDept(brandInfoVo.getBrandId(), brandInfoVo.getCompanyName(), brandInfoVo.getLeaderName(), brandInfoVo.getMobile());
        Long sysDeptId = IdGenUtils.getSnowId();
        sysDept.setBrandDeptId(sysDeptId);
        sysDeptMapper.insertDept(sysDept);
        //部门基础信息
        SysDept sysDeptReq = new SysDept();
        sysDeptReq.setBrandId(0L);
        List<SysDept> sysDeptList = sysDeptMapper.selectDeptList(sysDeptReq);
        if (sysDeptList.size() <= 0) {
            logger.info("----------初始化角色失败----------");
            throw new CustomException("初始化角色失败", HttpStatus.NOT_FOUND);
        }
        sysDeptList.forEach(item -> {
            item.setBrandDeptId(null);
            item.setBrandId(brandInfoVo.getBrandId());
            item.setParentId(sysDeptId);
            sysDeptMapper.insertDept(item);
        });
        return sysDept;
    }


    /**
     * 初始化部门
     *
     * @param dept
     */
    @Override
    @Transactional
    public boolean initializeDept(SysDept dept) {
        if (StringUtil.isEmpty(dept) || StringUtil.isEmpty(dept.getBrandId())) {
            return false;
        }
        //部门基础信息
        SysDept sysDeptReq = new SysDept();
        sysDeptReq.setBrandId(0L);
        List<SysDept> sysDeptList = sysDeptMapper.selectDeptList(sysDeptReq);
        if (sysDeptList.size() <= 0) {
            logger.info("----------初始化角色失败----------");
            return false;
        }
        sysDeptList.forEach(item -> {
            item.setBrandDeptId(null);
            item.setBrandId(dept.getBrandId());
            item.setStoreId(dept.getStoreId());
            item.setParentId(dept.getBrandDeptId());
            item.setAncestors(dept.getAncestors() + "," + dept.getBrandDeptId());
            sysDeptMapper.insertDept(item);
        });
        return true;
    }

    /**
     * 初始化品牌角色
     *
     * @param brandId
     */
    @Transactional
    public void initializeRole(Long brandId) {
        if (StringUtils.isEmpty(brandId)) {
            logger.info("----------参数错误----------");
            throw new CustomException("参数错误", HttpStatus.NOT_FOUND);
        }
        SysRole sysRole = new SysRole();
        sysRole.setBrandId(0L);
        //角色基础信息
        List<SysRole> sysRoleList = sysRoleMapper.selectRoleList(sysRole);
        if (sysRoleList.size() <= 0) {
            logger.info("----------初始化角色失败----------");
            throw new CustomException("初始化角色失败", HttpStatus.NOT_FOUND);
        }
        //新增角色角色
        sysRoleList.forEach(item -> {
            item.setBrandRoleId(null);
            item.setBrandId(brandId);
            sysRoleMapper.insertRole(item);
        });
    }

    /**
     * 初始品牌岗位
     *
     * @param brandId
     */
    @Transactional
    public void initializePost(Long brandId) {
        if (StringUtils.isEmpty(brandId)) {
            logger.info("----------参数错误----------");
            throw new CustomException("参数错误", HttpStatus.NOT_FOUND);
        }
        //品牌基础信息
        SysPost sysPost = new SysPost();
        sysPost.setBrandId(0L);
        sysPost.setStoreId(0l);
        List<SysPost> sysPostList = sysPostMapper.selectPostList(sysPost);
        if (sysPostList.size() <= 0) {
            logger.info("----------初始化岗位失败----------");
            throw new CustomException("初始化岗位失败", HttpStatus.NOT_FOUND);
        }
        sysPostList.forEach(item -> {
            item.setBrandPostId(null);
            item.setBrandId(brandId);
            sysPostMapper.insertPost(item);
        });
    }

    /**
     * 初始化品牌目录
     *
     * @param brandId
     */
    @Transactional
    public void initializeMenu(Long brandId) {
        if (StringUtils.isEmpty(brandId)) {
            logger.info("----------参数错误----------");
            throw new CustomException("参数错误", HttpStatus.NOT_FOUND);
        }
        SysMenu sysMenu = new SysMenu();
        sysMenu.setBrandId(0L);
        sysMenu.setParentId(0L);
        //一级菜单
        List<SysMenu> sysMenuList = sysMenuMapper.selectMenuList(sysMenu);
        if (sysMenuList.size() <= 0) {
            logger.info("----------初始化基础菜单目录失败----------");
            throw new CustomException("初始化基础菜单目录失败", HttpStatus.NOT_FOUND);
        }
        List<SysMenu> menuTrees = buildMenuTree(sysMenuList);
        menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
        //一级目录
        menuTrees.forEach(item -> {
            item.setMenuId(snowflake.nextId());
            item.setBrandId(brandId);
            sysMenuMapper.insertMenu(item);
            //二级目录
            item.getChildren().forEach(child -> {
                child.setMenuId(snowflake.nextId());
                child.setBrandId(brandId);
                child.setParentId(item.getMenuId());
                sysMenuMapper.insertMenu(child);
                //三级目录
                child.getChildren().forEach(btn -> {
                    btn.setMenuId(snowflake.nextId());
                    btn.setBrandId(brandId);
                    btn.setParentId(child.getMenuId());
                    sysMenuMapper.insertMenu(btn);
                });
            });
        });
    }

    /**
     * 构建前端所需要树结构
     *
     * @param menus 菜单列表
     * @return 树结构列表
     */
    public List<SysMenu> buildMenuTree(List<SysMenu> menus) {
        List<SysMenu> returnList = new ArrayList<SysMenu>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysMenu dept : menus) {
            tempList.add(dept.getMenuId());
        }
        for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext(); ) {
            SysMenu menu = (SysMenu) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(menu.getParentId())) {
                recursionFn(menus, menu);
                returnList.add(menu);
            }
        }
        if (returnList.isEmpty()) {
            returnList = menus;
        }
        return returnList;
    }


    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<SysMenu> list, SysMenu t) {
        // 得到子节点列表
        List<SysMenu> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenu tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
        List<SysMenu> tlist = new ArrayList<SysMenu>();
        Iterator<SysMenu> it = list.iterator();
        while (it.hasNext()) {
            SysMenu n = (SysMenu) it.next();
            if (n.getParentId().longValue() == t.getMenuId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenu> list, SysMenu t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }

    /**
     * 创建微信端用户
     *
     * @param sysUser
     */
    private void createUser(SysUser sysUser) {
        if (StringUtils.isEmpty(sysUser)) {
            return;
        }
        CommonWxUser wxUser = new CommonWxUser();
        wxUser.setBrandId(sysUser.getBrandId());
        wxUser.setBrandName(sysUser.getBrandName());
        wxUser.setWxType(BrandConstants.WE_CHAT_BRAND_ADMIN);
        wxUser.setStoreId(BrandConstants.DEFAULT_KEY);
        wxUser.setBrandUserId(sysUser.getBrandUserId());
        wxUser.setBrandName(sysUser.getNickName());
        wxUser.setUserName(sysUser.getNickName());
        wxUser.setNickname(sysUser.getNickName());
        wxUser.setPhone(sysUser.getUserName());
        wxUser.setStatus(UserStatus.OK.getCode());
        commonWxUserMapper.insert(wxUser);
    }

    /**
     * 用户绑定品牌管理员角色
     *
     * @param sysUser
     * @return
     */
    public boolean userBindingRole(SysUser sysUser) {
        if (StringUtil.isEmpty(sysUser)) {
            return false;
        }
        SysRole brandRole = sysRoleMapper.getBrandRole(sysUser.getBrandId(), BrandConstants.WE_CHAT_BRAND_ADMIN);
        if (StringUtil.isEmpty(brandRole)) {
            logger.info("-----------找不到角色信息" + brandRole + "-----------");
            return false;
        }
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setBrandId(sysUser.getBrandId());
        sysUserRole.setBrandUserId(sysUser.getWxUserId());
        sysUserRole.setBrandRoleId(brandRole.getBrandRoleId());
        sysUserRoleMapper.insert(sysUserRole);
        return true;
    }

}
